<?php

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * MYIO (mysql i/o abstraction)                                                  *
 *                                                                               *
 * Authors: Wess Cope <wcope@frenzylabs.com>                                     *
 *          Drew King <dking@frenzylabs.com>                                     *
 *                                                                               *
 * The MIT License                                                               *
 *                                                                               *
 * Copyright (c) 2007 FrenzyLabs (www.frenzylabs.com)                            *
 *                                                                               *
 * Permission is hereby granted, free of charge, to any person obtaining a copy  *
 * of this software and associated documentation files (the "Software"), to deal *
 * in the Software without restriction, including without limitation the rights  *
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell     *
 * copies of the Software, and to permit persons to whom the Software is         *
 * furnished to do so, subject to the following conditions:                      *
 *                                                                               *
 * The above copyright notice and this permission notice shall be included in    *
 * all copies or substantial portions of the Software.                           *
 *                                                                               *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR    *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,      *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE   *
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER        *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN     *
 * THE SOFTWARE.                                                                 *
 *                                                                               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

class MyIO
{
    private $cfg;
    private $db;
    private $schema;

    public function __construct($cfg)
    {
        $this->cfg = $cfg;

        $this->db = mysql_pconnect($cfg['host'], $cfg['user'], $cfg['pass']) or die(mysql_error());
		  mysql_select_db($cfg['db']) or die(mysql_error());

        $tables = mysql_query('SHOW TABLES');

        
        while (list($table) = mysql_fetch_array($tables))
        {
            $getColumns = "EXPLAIN $table";
            $columns = mysql_query($getColumns) or die(mysql_error());
            
            $t = new myioDriver($this->db, $table);
            
            while ($column = mysql_fetch_array($columns))
            {
                $t->addColumn($column);
            }

            $this->schema[$table] = $t;
  
        }
   
        //debug::dp($this->schema);
   
    }

    public function __get($table)
    {
        if (isset($this->schema[$table]))
        {
            return $this->schema[$table];
        }
        return FALSE;
    }

}

class myioDriver
{
   
   var $tableColumns;
   var $colVals;
   var $priKey;
   private $db;
   private $table;
   private $columns;

   public function __construct($db, $table)
   {
       $this->db = $db;
       $this->table = $table;
   }

   public function addColumn($columnData)
   {
       $this->columns[$columnData[0]] = array(
           'Type' => $columnData[1],
           'Null' => ($columnData[2] == "YES"),
           'Key' => $columnData[3],
           'Default' => $columnData[4],
           'Extra' => $columnData[5]
       );
   }

   public function __get($name)
   {
       if (array_key_exists($name, $this->columns))
       {
           return $this->columns[$name];
       }
   }
   function __set($var, $val = '')
   {
      $this->colVals[$var] = $val;        
   }//__set
   
   function desc($table = '')
   {

      $qry = "DESC {$table}";
      $res = mysql_query($qry) or die("desc: " . mysql_error());
      
      while($a = mysql_fetch_object($res))
      {
         $tCol[] = $a->Field;
      }
      return $tCol;
   }//desc
   
   
    function __call($func, $args = array())
    {
        $func = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '-\\1', $func));
        $func = explode('-', strtolower($func));
        
        for($xr = 0; $xr < count($args); $xr++) $args[$xr] = $this->mre($args[$xr]);
    
        switch($func[0])
        {
             
            case "find":
            
                switch ($func[2]) {
                 
                    case 'by':
                    
                        if ($func[4] == 'and') {
                            
                            $qry = "SELECT * FROM {$this->table} WHERE {$func[3]} = '{$args[0]}' AND {$func[5]} = '{$args[1]}'";
                            
                        } else {
                            
                            $qry = "SELECT * FROM {$this->table} WHERE {$func[3]} = '{$args[0]}'";
                        
                        }
                        
                    break;
                    
                    case 'where':
                    
                        switch ($func[4]) {
                            
                            case '':
                            
                                $qry = "SELECT * FROM {$this->table} WHERE {$args[0]}";
                                
                            break;
                            
                            case 'between':
                    
                                $whereItem = $this->mre($func[3]);	
                                $qry = "SELECT * FROM {$this->table} WHERE {$whereItem} BETWEEN {$args[0]} AND {$args[1]}";
                                
                                
                            break;
                            
                            case 'like':
                            
                                $whereItem = $this->mre($func[3]);	
                                $qry = "SELECT * FROM {$this->table} WHERE {$whereItem} LIKE '%{$args[0]}%'";
                            
                            break;
                            
                            default:
                                    
                            	$whereItem = $this->mre($func[3]);					
                                $qry = "SELECT * FROM {$this->table} WHERE {$whereItem} = '{$args[0]}'";
                                
                            break;
                            
                        }
            
                        if (isset($func[5])) {
                            
                            switch ($func[5]) {
                                
                                case 'ordered':
                                
                                    if (isset($func[7]) && $func[7] == 'limited') {
                                        
                                        $qry .= " ORDER BY {$args[count($args) - 3]}";
                                        $qry .= " LIMIT {$args[count($args) - 2]}, {$args[count($args) - 1]}";
                                        
                                    } else {
                                        
                                        $qry .= " ORDER BY {$args[count($args) - 1]}";
                                        
                                    }
                                    
                                break;
                                
                                case 'limited':
                                
                                    $qry .= " LIMIT {$args[count($args) - 2]}, {$args[count($args) - 1]}";
                                    
                                
                                break;
                                
                            }
                            
                        }
                        
                    break;
                    
                    default:
                    
                        $qry = "SELECT * FROM {$this->table}";
                        
                    break;   
                    
                }
                
                $res = mysql_query($qry) or die("__call: " . $qry . " :: (findLike):" . mysql_error());
                
                while($obj = mysql_fetch_object($res))
                {
                 $ary[] = $obj;
                }
                
                return $ary;
               
            break;
            
            case "get":
            
                if($func[2] == 'where') {
                    
                    if ($func[1] == 'first') { $func[1] = '*'; }
                    
                    if (!isset($func[3])) { $func[3] = true; }
                        
                    switch ($func[3]) {
                        
                        case 'between':
                        
                            $whereItem = $this->mre($func[3]);	
                            $qry = "SELECT {$func[1]} FROM {$this->table} WHERE {$whereItem} BETWEEN {$args[0]} AND {$args[1]}";
                            
                        break;
                        
                        default:
                                
                        	$whereItem = $this->mre($func[3]);					
                            $qry = "SELECT {$func[1]} FROM {$this->table} WHERE {$whereItem} = '{$args[0]}'";
                            
                        break;
                        
                    }
                    
                    if (isset($func[4])) {
                        
                        switch ($func[4]) {
                            
                            case 'ordered':
                        
                                if (isset($func[6]) && $func[6] == 'limited') {
                                    
                                    $qry .= " ORDER BY {$args[count($args) - 3]}";
                                    $qry .= " LIMIT {$args[count($args) - 2]}, {$args[count($args) - 1]}";
                                    
                                } else {
                                    
                                    $qry .= " ORDER BY {$args[count($args) - 1]}";
                                    
                                }
                                
                            break;
                            
                            case 'limited':
                            
                                $qry .= " LIMIT {$args[count($args) - 2]}, {$args[count($args) - 1]}";
                                
                            
                            break;
                            
                        }
                        
                    }
                    
                }
               else
               {
                  die('__call (get): Function not supported: ' . $qry);
               }
            
               $res = mysql_query($qry) or die("__call (get): " . mysql_error() . "<br/>{$qry}");
               
               return mysql_fetch_object($res);
            
            break;
            
            case "delete": //deleteById(id);
               $qry = "DELETE FROM {$this->table} WHERE {$func[2]} = '{$args[0]}'";
               return mysql_query($qry) or die("__call (delete): " . mysql_error());
            break;
            
        default:
           die("Function is not supported");
        break;
        }

    }//__call
   
   
   
   function findAll()
   {
      $qry = "SELECT * FROM {$this->table}";
      $res = mysql_query($qry) or die("findAll: " .mysql_error() . "<br>query: " . $qry);
      
      while($obj = mysql_fetch_object($res))
      {
         $ary[] = $obj;
      }
      
      return $ary;
   }//findAll
   
   function findAllWhere($where)
   {
      $where = $this->mre($where);
      $qry = "SELECT * FROM {$this->table} WHERE {$where}";
      $res = mysql_query($qry) or die("findAllWhere: " . mysql_error());
      
      while($obj = mysql_fetch_object($res))
      {
         $ary[] = $obj;
      }
      
      return $ary;
   }//findAllWhere
   
   
   function save()
   {
      if(!empty($this->colVals["id"]))
      {
         //UPDATE table SET blah = 'bla', blee='bl' WHERE do='da'
         $qry = "UPDATE {$this->table} SET ";
         
         foreach($this->colVals as $name => $value)
         {
            $name = $this->mre($name);
            $value = $this->mre($value);
            
            $qryAry[] = "{$name}='{$value}'";
         }
         $qry .= implode(',', $qryAry);
         
         $id = $this->mre($this->colVals["id"]);
         $qry .= " WHERE id = {$id}";

         return mysql_query($qry) or die('save: ' . mysql_error());
      }
      else
      {
         //INSERT INTO table (blah, blee) VALUES ('bla', 'bl')
   
         foreach($this->colVals as $name => $value)
         {
            $fields[] = $this->mre($name);
            $values[] = "'" . $this->mre($value) . "'";
         }
         
         $fieldNames  = implode(',', $fields);
         $fieldValues = implode(',', $values);
         
         $qry = "INSERT INTO {$this->table} ({$fieldNames}) VALUES ({$fieldValues})";
         
         if(mysql_query($qry))
         {
            $this->colVals["id"] = mysql_insert_id();
            return true;
         }
         else
         {
            die('save: ' . mysql_error());
         }
         
      }
      
   }//end save
   
   function query($qry)
   {
      if(empty($qry))
      {
         die("query: a query is required for this function");
      }
      
      $res = mysql_query($qry) or die("query: {$qry} <br>" . mysql_error());
      
      $o = array();
      
      while($obj = @mysql_fetch_object($res))
      {
         $o[] = $obj;
      }
      return $o;
   }

   function fieldCount($where = '')
   {
      $where = (empty($where))? '' : ' WHERE ' . $this->mre($where);
      $qry = "SELECT count(*) FROM {$this->table}" . $where;
      $res = mysql_query($qry) or die("fieldCount Error: " . mysql_error() . "<br>{$qry}");
      list($cnt) = mysql_fetch_array($res);
      
      return $cnt;
   }

	private function mre($item)
	{
		return mysql_real_escape_string($item);
	}
    
}//end class

?>
